package com.aliyun.heiyu.powermaster.server.manager;

import com.aliyun.heiyu.common.util.DateUtil;
import com.aliyun.heiyu.common.util.TimeConvertUtil;
import com.aliyun.heiyu.powermaster.proto.DeviceInfo;
import com.aliyun.heiyu.powermaster.proto.StrategyAction;
import com.aliyun.heiyu.powermaster.proto.StrategyControlHistory;
import com.aliyun.heiyu.powermaster.proto.StrategyDetail;
import com.aliyun.heiyu.powermaster.server.dao.Strategy2DeviceDao;
import com.aliyun.heiyu.powermaster.server.dao.StrategyActionDao;
import com.aliyun.heiyu.powermaster.server.dao.StrategyActionHistoryDao;
import com.aliyun.heiyu.powermaster.server.dao.StrategyDao;
import com.aliyun.heiyu.powermaster.server.dao.entity.*;
import com.aliyun.heiyu.powermaster.server.dao.impl.Strategy2DeviceImpl;
import com.aliyun.heiyu.powermaster.server.dao.impl.StrategyActionHistoryImpl;
import com.aliyun.heiyu.powermaster.server.dao.impl.StrategyActionImpl;
import com.aliyun.heiyu.powermaster.server.dao.impl.StrategyImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class StrategyManager implements StrategyManagerInterface {
    private static final Logger logger = LoggerFactory.getLogger(StrategyManager.class);

    private StrategyDao strategyDao;
    private StrategyActionDao strategyActionDao;
    private Strategy2DeviceDao strategy2DeviceDao;
    private StrategyActionHistoryDao actionHistoryDao;
    private DeviceManager deviceManager;

    private Map<Integer,StrategyDetail> catchMap;

    private static volatile StrategyManager instance;

    public static StrategyManager getInstance() {
        synchronized (StrategyManager.class) {
            if (instance == null) {
                instance = new StrategyManager();
            }
        }

        return instance;
    }

    private StrategyManager() {
        this.strategyDao = new StrategyImpl();
        this.strategyActionDao = new StrategyActionImpl();
        this.strategy2DeviceDao = new Strategy2DeviceImpl();
        this.actionHistoryDao = new StrategyActionHistoryImpl();
        deviceManager = DeviceManagerImpl.getInstance();
        initCache();
    }

    public void initCache(){
        catchMap = new HashMap<>();
        List<StrategyEntity> strategyEntities = strategyDao.findAll();
        if(strategyEntities != null && strategyEntities.size() != 0){
            List<StrategyActionEntity> actionEntities = strategyActionDao.findAll();
            for (StrategyEntity strategyEntity : strategyEntities) {
                StrategyDetail.Builder builder = StrategyDetail.newBuilder();
                int strategyID = strategyEntity.getStrategyID() == null ? 0 : strategyEntity.getStrategyID();
                builder.setStrategyID(strategyID);
                builder.setStrategyName(strategyEntity.getStrategyName() == null ? "" : strategyEntity.getStrategyName());
                builder.setSwitchOn(strategyEntity.getSwitchOn());
                int type = strategyEntity.getType();
                String controlLevel = "0";
                builder.setType(type);
                if (strategyEntity.getBusiness() != null) {
                    builder.setBusiness(strategyEntity.getBusiness());
                }
                if (strategyEntity.getControlLevel() != null) {
                    controlLevel = strategyEntity.getControlLevel();
                }
                builder.setControlLevel(controlLevel);
                builder.setModifyTime(strategyEntity.getModifiedTime().getTime());
                long usedTime = (System.currentTimeMillis() - strategyEntity.getModifiedTime().getTime()) / 1000;
                builder.setUsedTime(usedTime);
                List<StrategyAction> actionList = new ArrayList<>();
                //type = 1 不加动作
                for (StrategyActionEntity actionEntity : actionEntities) {
                    if (strategyEntity.getStrategyID().equals(actionEntity.getStrategyID())) {
                        StrategyAction.Builder builder2 = StrategyAction.newBuilder();
                        builder2.setActionName(actionEntity.getActionName() == null ? "" : actionEntity.getActionName());
                        builder2.setFmin(actionEntity.getFmin() == null ? "" : actionEntity.getFmin());
                        builder2.setCapTo(actionEntity.getCapTo() == null ? "" : actionEntity.getCapTo());
                        builder2.setCapType(actionEntity.getCapType() == null ? "" : actionEntity.getCapType());
                        StrategyAction.ActionCondition.Builder builder3 = StrategyAction.ActionCondition.newBuilder();
                        builder3.setState(actionEntity.getState() == null ? "" : actionEntity.getState());
                        builder3.setMaxCPUUsage(actionEntity.getMaxCPUUsage() == null ? "" : actionEntity.getMaxCPUUsage());
                        builder3.setMinCPUUsage(actionEntity.getMinCPUUsage() == null ? "" : actionEntity.getMinCPUUsage());
                        builder3.setMaxPower(actionEntity.getMaxPower() == null ? "" : actionEntity.getMaxPower());
                        builder3.setMinPower(actionEntity.getMinPower() == null ? "" : actionEntity.getMinPower());
                        builder3.setStartTime(actionEntity.getStartTime() == null ? "" : actionEntity.getStartTime());
                        builder3.setEndTime(actionEntity.getEndTime() == null ? "" : actionEntity.getEndTime());
                        builder2.setActionCondition(builder3);
                        actionList.add(builder2.build());
                    }
                }
                builder.addAllStrategyActions(actionList);
                catchMap.put(strategyID, builder.build());
            }
        }
    }


    /**
     * 新增一条策略
     * @param strategyDetail
     * @return
     */
    //todo 如果多进程在设备详情编辑策略，会出现重复数据
    public boolean insert(StrategyDetail strategyDetail) {
        boolean ret = true;
        //新增策略
        strategyDetail = strategyDetail.toBuilder().setModifyTime(System.currentTimeMillis()).build();
        List<StrategyAction> strategyActionsList = strategyDetail.getStrategyActionsList();
        List<StrategyAction> actionList = new ArrayList<>();
        for (StrategyAction action : strategyActionsList){
            StrategyAction.ActionCondition actionCondition = action.getActionCondition();
            if(actionCondition == null){
                StrategyAction.ActionCondition.Builder builder = StrategyAction.ActionCondition.newBuilder();
                action = action.toBuilder().setActionCondition(builder).build();
            }
            actionList.add(action);
        }
        strategyDetail = strategyDetail.toBuilder().clearStrategyActions().addAllStrategyActions(actionList).build();
        StrategyEntity strategyEntity = detailToEntity(strategyDetail);
        Integer insertID = strategyDao.insert(strategyEntity);
        //新增策略动作
        //strategyActionsList = strategyDetail.getStrategyActionsList();
        strategyActionsList = actionList;
        ret &= updateStrategyActions(insertID, strategyActionsList);
        //更新缓存
        if(ret){
            strategyDetail = strategyDetail.toBuilder().setStrategyID(insertID).build();
            catchMap.put(insertID,strategyDetail);

        }
        return ret;
    }

    /**
     * 策略的部分更新: 两种情况：第一个只更新switchOn，第二种更新除switchOn之外的其他的所有
     */
    //todo 如果多进程在设备详情编辑策略，会出现重复数据
    public boolean patch(StrategyDetail strategyDetail) {
        boolean ret = true;
        int strategyID = strategyDetail.getStrategyID();
        strategyDetail = strategyDetail.toBuilder().setModifyTime(System.currentTimeMillis()).build();
        List<StrategyAction> strategyActionsList = strategyDetail.getStrategyActionsList();
        List<StrategyAction> actionList = new ArrayList<>();
        for (StrategyAction action : strategyActionsList){
            StrategyAction.ActionCondition actionCondition = action.getActionCondition();
            if(actionCondition == null){
                StrategyAction.ActionCondition.Builder builder = StrategyAction.ActionCondition.newBuilder();
                action = action.toBuilder().setActionCondition(builder).build();
            }
            actionList.add(action);
        }
        strategyDetail = strategyDetail.toBuilder().clearStrategyActions().addAllStrategyActions(actionList).build();
        StrategyEntity strategyEntity = detailToEntity(strategyDetail);
        String strategyName = strategyDetail.getStrategyName();
        //更新switchOn: 根据strategyName是否有值来判断是否更新
        if (strategyName == null || strategyName.isEmpty()) {
            //更新策略开关
            ret &= strategyDao.updateSwitch(strategyEntity);
            if(ret){
                StrategyDetail strategyDetail1 = catchMap.get(strategyID);
                if(strategyDetail1 != null){
                    strategyDetail1 = strategyDetail1.toBuilder()
                        .setSwitchOn(strategyDetail.getSwitchOn())
                        .setModifyTime(strategyDetail.getModifyTime())
                        .build();
                } else {
                    strategyDetail1 = fromDB(strategyID);
                }
                if(strategyDetail1 != null){
                    catchMap.put(strategyID,strategyDetail1);
                } else {
                    catchMap.remove(strategyID);
                }
            }
            return ret;
        }
        //更新策略
        ret &= strategyDao.update(strategyEntity);
        if(!ret){
            return ret;
        }

        //更新策略动作（删除再添加）
        strategyActionsList = actionList;
        //List<StrategyAction> strategyActionsList = strategyDetail.getStrategyActionsList();
        ret &= updateStrategyActions(strategyID, strategyActionsList);
        //更新缓存
        if(ret){
            StrategyDetail strategyDetail1 = catchMap.get(strategyID);
            if(strategyDetail1 != null){
                strategyDetail = strategyDetail.toBuilder().setSwitchOn(strategyDetail1.getSwitchOn()).setType(strategyDetail1.getType()).build();
            } else {
                strategyDetail = fromDB(strategyID);
            }
            if(strategyDetail != null){
                catchMap.put(strategyID,strategyDetail);
            } else {
                catchMap.remove(strategyID);
            }
        }
        return ret;
    }

    /**
     * 删除某条策略
     */
    public boolean delete(String[] ids) {
        //同时删除三个表
        boolean ret = strategyDao.delete(ids);
        ret &= strategyActionDao.deleteByStrategyIDs(ids);
        ret &= strategy2DeviceDao.deleteByStrategyIDs(ids);
        for(String s : ids){
            catchMap.remove(s);
        }
        return ret;
    }

    public int getCountByCondition(String str, String type){
        return strategyDao.getCountByCondition(str,type);
    }

    public List<StrategyDetail> getByCondition(String str, String type){
        ArrayList<StrategyDetail> list = new ArrayList<>();
        List<StrategyEntity> entities = strategyDao.findByCondition(str, type);
        if(entities == null){
            return list;
        }
        return convertToStrategyDetail(entities);
    }

    public List<StrategyDetail> getByCondition(String str, String type, int start, int size){
        ArrayList<StrategyDetail> list = new ArrayList<>();
        List<StrategyEntity> entities = strategyDao.findByCondition(str, type, start, size);
        if(entities == null){
            return list;
        }
        return convertToStrategyDetail(entities);
    }

    public StrategyDetail getStrategy(int id) {
        StrategyEntity entity = strategyDao.findOne(id);
        if (null == entity) {
            return null;
        }
        return convertToStrategyDetail(entity);
    }

    public boolean deleteDevices(Object[] deviceList){
        if(deviceList == null || deviceList.length == 0){
            return true;
        }
        return strategy2DeviceDao.delete(deviceList);
    }

    @Override
    public boolean deleteDevices(int strategyID, Object[] deviceList) {
        if(deviceList == null || deviceList.length == 0){
            return true;
        }
        return strategy2DeviceDao.delete(strategyID, deviceList);
    }

    @Override
    public boolean deleteStrategyDevices(int strategyID, Object[] deviceList) {
        if(deviceList == null || deviceList.length == 0){
            return true;
        }
        return strategy2DeviceDao.deleteStrategyIdOrInDevices(strategyID, deviceList);
    }

    public boolean insertDevice(Strategy2DeviceEntity entity){
        return strategy2DeviceDao.insert(entity);
    }

    public int getCountHistoryByCondition(String deviceId){
        return actionHistoryDao.count(deviceId);
    }

    public List<StrategyControlHistory> getHistoryByCondition(String deviceId){
        List<StrategyActionHistoryEntity> entityList = actionHistoryDao.getByCondition(deviceId);
        return toStrategyControlHistory(entityList);
    }

    public List<StrategyControlHistory> getHistoryByCondition(String deviceId, int start, int size){
        List<StrategyActionHistoryEntity> entityList = actionHistoryDao.getByCondition(deviceId, start, size);
        return toStrategyControlHistory(entityList);
    }

    public StrategyDetail getStrategyDetailByDeviceId(String deviceID){
        StrategyEntity entity = strategyDao.findOneByDevice(deviceID);
        if(entity == null){
            return null;
        }
        //不要设备集合
        StrategyDetail strategyDetail = catchMap.get(entity.getStrategyID());
        if(strategyDetail == null){
            strategyDetail = fromDB(entity);
        }
        long usedTime = (System.currentTimeMillis() - entity.getModifiedTime().getTime()) / 1000;
        StrategyDetail.Builder builder = strategyDetail.toBuilder();
        builder.setUsedTime(usedTime);
        return builder.build();
    }

    public StrategyEntity getStrategyByDeviceId(String sn) {
        return strategyDao.findOneByDevice(sn);
    }

    public boolean virtyStrategyIdExit(int id){
        StrategyEntity strategyEntity = strategyDao.findOne(id);
        if(strategyEntity == null){
            return false;
        }
        return true;
    }

    public boolean virtyStrategyNameExit(String name){
        StrategyEntity strategyEntity = strategyDao.findByName(name);
        if(strategyEntity == null){
            return false;
        }
        return true;
    }

    public boolean insertActionHistory(StrategyActionHistoryEntity entity) {
        boolean ret = actionHistoryDao.insert(entity);
        return ret;
    }

    public List<StrategyDetail> getAllStrategiesOfOn() {
        List<StrategyEntity> strategyEntities = strategyDao.findAllOfOn();
        List<StrategyDetail> strategyDetailList = convertToStrategyDetail(strategyEntities);
        return strategyDetailList;
    }

    public List<StrategyDetail> getAllStrategiesOfOn1() {
        List<StrategyEntity> strategyEntities = strategyDao.findAllOfOn();
        List<StrategyDetail> strategyDetailList = convertToStrategyDetail1(strategyEntities);
        return strategyDetailList;
    }

    @Override
    public Strategy2DeviceEntity findByDeviceId(String sn) {
        return strategy2DeviceDao.findByDeviceId(sn);
    }

    private List<StrategyControlHistory> toStrategyControlHistory(List<StrategyActionHistoryEntity> entityList){
        List<StrategyControlHistory> list = new ArrayList<>();
        if(null == entityList || entityList.size() == 0){
            return list;
        }
        list = entityList.stream().map(o -> toStrategyControlHistory(o)).collect(Collectors.toList());
        return list;
    }

    private StrategyControlHistory toStrategyControlHistory(StrategyActionHistoryEntity entity){
        StrategyControlHistory.Builder builder = StrategyControlHistory.newBuilder();
        String controlName = "";
        if("power_off".equals(entity.getActionName())){
            if(entity.getSwitchOn()){
                controlName = "加入低功耗缓存池";
            } else {
                controlName = "移出低功耗缓存池";
            }
        } else if("shut_down".equals(entity.getActionName())){
            if(entity.getSwitchOn()){
                controlName = "执行关机/休眠";
            } else {
                controlName = "执行开机/唤醒";
            }
        } else {
            controlName = (entity.getSwitchOn() ? "开启" : "关闭") + entity.getActionName();
        }
        builder.setControlName(controlName);
        Timestamp time = entity.getTime();
        String timeStr = DateUtil.stamp2String(time, new SimpleDateFormat(TimeConvertUtil.DATETIME_PATTERN));
        builder.setControlTime(timeStr);
        List<String> statusList = getActionStatus(entity.getDeviceID(), time);
        builder.addAllStatus(statusList);
        return builder.build();
    }

    private StrategyActionEntity toStrategyActionEntity(int strategyID, StrategyAction strategyAction){
        StrategyActionEntity actionEntity = new StrategyActionEntity();
        actionEntity.setStrategyID(strategyID);
        actionEntity.setActionName(strategyAction.getActionName());
        actionEntity.setFmin(strategyAction.getFmin());
        actionEntity.setCapType(strategyAction.getCapType());
        actionEntity.setCapTo(strategyAction.getCapTo());
        StrategyAction.ActionCondition actionCondition = strategyAction.getActionCondition();
        actionEntity.setState(actionCondition.getState());
        actionEntity.setMinCPUUsage(actionCondition.getMinCPUUsage());
        actionEntity.setMaxCPUUsage(actionCondition.getMaxCPUUsage());
        actionEntity.setMinPower(actionCondition.getMinPower());
        actionEntity.setMaxPower(actionCondition.getMaxPower());
        actionEntity.setStartTime(actionCondition.getStartTime());
        actionEntity.setEndTime(actionCondition.getEndTime());
        return actionEntity;
    }

    /**
     * 更新策略动作：统一删除旧的策略动作，然后新增新的策略动作
     */
    private boolean updateStrategyActions(Integer strategyID, List<StrategyAction> strategyActionsList) {
        boolean ret = true;
        ret &= strategyActionDao.deleteByStrategyId(strategyID);
        if(!ret){
            return ret;
        }

        for (StrategyAction strategyAction : strategyActionsList) {
            StrategyActionEntity actionEntity = toStrategyActionEntity(strategyID,strategyAction);
            ret &= strategyActionDao.insert(actionEntity);
            if(!ret){
                return ret;
            }
        }
        return ret;
    }

    private StrategyEntity detailToEntity(StrategyDetail strategyDetail){
        StrategyEntity strategyEntity = new StrategyEntity();
        strategyEntity.setStrategyName(strategyDetail.getStrategyName());
        strategyEntity.setSwitchOn(strategyDetail.getSwitchOn());
        int type = strategyDetail.getType();
        strategyEntity.setType(type);
        strategyEntity.setControlLevel(strategyDetail.getControlLevel());
        strategyEntity.setBusiness(strategyDetail.getBusiness());
        Timestamp nowTime = new Timestamp(strategyDetail.getModifyTime());
        strategyEntity.setModifiedTime(nowTime);
        strategyEntity.setStrategyID(strategyDetail.getStrategyID());
        return strategyEntity;
    }

    private List<String> getActionStatus(String deviceId, Timestamp time){
        List<String> actionStatus = actionHistoryDao.getActionStatus(deviceId, time);
        if(actionStatus == null){
            return new ArrayList<String>();
        }
        return actionStatus;
    }

    /**
     * 根据策略ID获取该策略下的所有设备的设备信息
     */
    private List<DeviceInfo> getDeviceInfosByStrategyID(Integer strategyID) {
        List<DeviceInfo> deviceInfos = new ArrayList<>();
        List<Strategy2DeviceEntity> entityList = strategy2DeviceDao.findByStrategyID(strategyID);
        if(entityList == null || entityList.size() == 0){
            return deviceInfos;
        }
        for (Strategy2DeviceEntity entity : entityList) {
            String deviceID = entity.getDeviceID();
            DeviceInfo info = getDeviceInfoBySN(deviceID);
            if(info == null){
                continue;
            }
            deviceInfos.add(info);
        }
        return deviceInfos;
    }

    /**
     * 根据获取策略下的所有设备的设备信息
     */
    private List<DeviceInfo> getDeviceInfos() {
        List<DeviceInfo> deviceInfos = new ArrayList<>();
        List<Strategy2DeviceEntity> entityList = strategy2DeviceDao.findAll();
        if(entityList == null){
            return deviceInfos;
        }
        for (Strategy2DeviceEntity entity : entityList) {
            Integer strategyID = entity.getStrategyID();
            String deviceID = entity.getDeviceID();
            DeviceInfo info = getDeviceInfoBySN(deviceID);
            if(info == null){
                continue;
            }
            info = info.toBuilder().setStrategyId(strategyID).build();
            deviceInfos.add(info);
        }
        return deviceInfos;
    }

    private DeviceInfo getDeviceInfoBySN(String sn) {
        DeviceCommonEntity device = deviceManager.findOneDeviceCommon(sn);
        if(null==device){
            return null;
        }
        DeviceInfo.Builder builder = DeviceInfo.newBuilder();
        builder.setIp(device.getIp() == null ? "" : device.getIp());
        builder.setEquipmentNumber(device.getDevice_id() == null ? "" : device.getDevice_id());
        builder.setDeviceType(device.getType() == null ? "" : device.getType());
        return builder.build();
    }

    private List<StrategyDetail> convertToStrategyDetail(List<StrategyEntity> strategyEntities) {
        List<StrategyDetail> strategyDetailList = new ArrayList<>();
        if (null == strategyEntities || strategyEntities.size() == 0) {
            return strategyDetailList;
        }
        HashMap<Integer, List<DeviceInfo>> map = new HashMap<>();
        List<DeviceInfo> deviceInfos = getDeviceInfos();
        Set<Integer> strategyIdSet = strategyEntities.stream().map(o -> o.getStrategyID()).collect(Collectors.toSet());
        for(Integer s : strategyIdSet){
            ArrayList<DeviceInfo> infoList = new ArrayList<>();
            map.put(s,infoList);
        }
        for(DeviceInfo info : deviceInfos){
            int strategyId = info.getStrategyId();
            List<DeviceInfo> deviceInfos1 = map.get(strategyId);
            if(deviceInfos1 != null){
                deviceInfos1.add(info);
            }
        }
        for (StrategyEntity strategyEntity : strategyEntities){
            Integer strategyID = strategyEntity.getStrategyID();
            StrategyDetail strategyDetail = catchMap.get(strategyID);
            if(strategyDetail == null){
                strategyDetail = fromDB(strategyEntity);
            }
            long usedTime = (System.currentTimeMillis() - strategyEntity.getModifiedTime().getTime()) / 1000;
            StrategyDetail.Builder builder = strategyDetail.toBuilder();
            builder.setUsedTime(usedTime);
            builder.addAllDeviceInfos(map.get(strategyID));
            strategyDetailList.add(builder.build());
        }
        return strategyDetailList;
    }

    //故意从数据库拉取数据，校验数据完整性
    private List<StrategyDetail> convertToStrategyDetail1(List<StrategyEntity> strategyEntities) {
        List<StrategyDetail> strategyDetailList = new ArrayList<>();
        if (null == strategyEntities || strategyEntities.size() == 0) {
            return strategyDetailList;
        }
        List<StrategyActionEntity> actionEntities = strategyActionDao.findAll();

        for (StrategyEntity strategyEntity : strategyEntities) {
            StrategyDetail.Builder builder = StrategyDetail.newBuilder();
            builder.setStrategyID(strategyEntity.getStrategyID()==null?0:strategyEntity.getStrategyID());
            builder.setStrategyName(strategyEntity.getStrategyName()==null?"":strategyEntity.getStrategyName());
            builder.setSwitchOn(strategyEntity.getSwitchOn());
            int type = strategyEntity.getType();
            String controlLevel = "0";
            builder.setType(type);
            if (strategyEntity.getBusiness() != null) {
                builder.setBusiness(strategyEntity.getBusiness());
            }
            if (strategyEntity.getControlLevel() != null) {
                controlLevel = strategyEntity.getControlLevel();
            }
            builder.setControlLevel(controlLevel);
            long usedTime = (System.currentTimeMillis() - strategyEntity.getModifiedTime().getTime()) / 1000;
            builder.setUsedTime(usedTime);
            List<StrategyAction> actionList = new ArrayList<>();
            //type = 1 不加动作
            for (StrategyActionEntity actionEntity : actionEntities) {
                if (strategyEntity.getStrategyID().equals(actionEntity.getStrategyID())) {
                    StrategyAction.Builder builder2 = StrategyAction.newBuilder();
                    builder2.setActionName(actionEntity.getActionName()==null?"":actionEntity.getActionName());
                    builder2.setFmin(actionEntity.getFmin()==null?"":actionEntity.getFmin());
                    builder2.setCapTo(actionEntity.getCapTo()==null?"":actionEntity.getCapTo());
                    builder2.setCapType(actionEntity.getCapType()==null?"":actionEntity.getCapType());
                    StrategyAction.ActionCondition.Builder builder3 = StrategyAction.ActionCondition.newBuilder();
                    builder3.setState(actionEntity.getState()==null?"":actionEntity.getState());
                    builder3.setMaxCPUUsage(actionEntity.getMaxCPUUsage()==null?"":actionEntity.getMaxCPUUsage());
                    builder3.setMinCPUUsage(actionEntity.getMinCPUUsage()==null?"":actionEntity.getMinCPUUsage());
                    builder3.setMaxPower(actionEntity.getMaxPower()==null?"":actionEntity.getMaxPower());
                    builder3.setMinPower(actionEntity.getMinPower()==null?"":actionEntity.getMinPower());
                    builder3.setStartTime(actionEntity.getStartTime()==null?"":actionEntity.getStartTime());
                    builder3.setEndTime(actionEntity.getEndTime()==null?"":actionEntity.getEndTime());
                    builder2.setActionCondition(builder3);
                    actionList.add(builder2.build());
                }
            }
            builder.addAllStrategyActions(actionList);
            List<DeviceInfo> deviceInfos = getDeviceInfosByStrategyID(strategyEntity.getStrategyID());
            builder.addAllDeviceInfos(deviceInfos);
            strategyDetailList.add(builder.build());
        }
        return strategyDetailList;
    }

    private StrategyDetail convertToStrategyDetail(StrategyEntity strategyEntity){
        Integer strategyID = strategyEntity.getStrategyID();
        StrategyDetail strategyDetail = catchMap.get(strategyID);
        if(strategyDetail == null){
            strategyDetail = fromDB(strategyEntity);
        }
        long usedTime = (System.currentTimeMillis() - strategyEntity.getModifiedTime().getTime()) / 1000;
        StrategyDetail.Builder builder = strategyDetail.toBuilder();
        builder.setUsedTime(usedTime);
        builder.addAllDeviceInfos(getDeviceInfosByStrategyID(strategyID));
        return builder.build();
    }

    private StrategyDetail fromDB(int strategyID){
        StrategyEntity one = strategyDao.findOne(strategyID);
        if(one == null){
            return null;
        }
        return fromDB(one);
    }

    private StrategyDetail fromDB(StrategyEntity strategyEntity){
        StrategyDetail.Builder builder = StrategyDetail.newBuilder();
        int strategyID = strategyEntity.getStrategyID()==null?0:strategyEntity.getStrategyID();
        builder.setStrategyID(strategyID);
        builder.setStrategyName(strategyEntity.getStrategyName()==null?"":strategyEntity.getStrategyName());
        builder.setSwitchOn(strategyEntity.getSwitchOn());
        int type = strategyEntity.getType();
        String controlLevel = "0";
        builder.setType(type);
        if (strategyEntity.getBusiness() != null) {
            builder.setBusiness(strategyEntity.getBusiness());
        }
        if (strategyEntity.getControlLevel() != null) {
            controlLevel = strategyEntity.getControlLevel();
        }
        builder.setControlLevel(controlLevel);
        builder.setModifyTime(strategyEntity.getModifiedTime().getTime());
        long usedTime = (System.currentTimeMillis() - strategyEntity.getModifiedTime().getTime()) / 1000;
        builder.setUsedTime(usedTime);
        List<StrategyActionEntity> actionEntities = strategyActionDao.findByStrategyID(strategyID);
        if(actionEntities != null && actionEntities.size() != 0){
            //type = 1 不加动作
            for (StrategyActionEntity actionEntity : actionEntities) {
                if (strategyEntity.getStrategyID().equals(actionEntity.getStrategyID())) {
                    StrategyAction.Builder builder2 = StrategyAction.newBuilder();
                    builder2.setActionName(actionEntity.getActionName()==null?"":actionEntity.getActionName());
                    builder2.setFmin(actionEntity.getFmin()==null?"":actionEntity.getFmin());
                    builder2.setCapTo(actionEntity.getCapTo()==null?"":actionEntity.getCapTo());
                    builder2.setCapType(actionEntity.getCapType()==null?"":actionEntity.getCapType());
                    StrategyAction.ActionCondition.Builder builder3 = StrategyAction.ActionCondition.newBuilder();
                    builder3.setState(actionEntity.getState()==null?"":actionEntity.getState());
                    builder3.setMaxCPUUsage(actionEntity.getMaxCPUUsage()==null?"":actionEntity.getMaxCPUUsage());
                    builder3.setMinCPUUsage(actionEntity.getMinCPUUsage()==null?"":actionEntity.getMinCPUUsage());
                    builder3.setMaxPower(actionEntity.getMaxPower()==null?"":actionEntity.getMaxPower());
                    builder3.setMinPower(actionEntity.getMinPower()==null?"":actionEntity.getMinPower());
                    builder3.setStartTime(actionEntity.getStartTime()==null?"":actionEntity.getStartTime());
                    builder3.setEndTime(actionEntity.getEndTime()==null?"":actionEntity.getEndTime());
                    builder2.setActionCondition(builder3);
                    builder.addStrategyActions(builder2.build());
                }
            }
        }
        return builder.build();
    }

    public List<StrategyDetail> getAllAutoStrategiesOfOn() {
        List<StrategyEntity> strategyEntities = strategyDao.findAllAutoOfOn();
        List<StrategyDetail> strategyDetailList = convertToStrategyDetail(strategyEntities);
        return strategyDetailList;
    }



}
